﻿using HtmlAgilityPack;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WhatCatch.Core
{
    /// <summary>
    /// 爬虫服务
    /// 只做服务级别的处理，或线程级别的调控
    /// </summary>
    public class CrawlerService
    {
        //ILogger logger = LogManager.GetCurrentClassLogger();
        ICrawlerLog _crawlerLog;

        CrawlerConfig _config;
        IListPageHandler _listPageHandler;
        IDetailPageHandler _detailPageHandler;
        DataContainerBase _dataContainer;
        IHttpHandler _httpHandler;
        bool isRun = false;

        public CrawlerService(string startUrl, CrawlerConfig config)
        {
            _crawlerLog = new CrawlerLog();

            _config = config;
            _dataContainer = new DataContainer();
            //_dataContainer = new DataContainer_List1Lock();//时间1:06:16
            //_dataContainer = new DataContainer_List3Lock();//时间1:06:07 内存140.8M
            //_dataContainer = new DataContainer_Dict1Lock();//时间1:00:00 内存100.4M
            //_dataContainer = new DataContainer_Dict3Lock();//时间1:02:00 内存101.5M
            //_dataContainer = new DataContainer_DictCon();
            //_dataContainer = new DataContainer_Hash1Lock();//时间1:00:01 内存97.8M
            //_dataContainer = new DataContainer_Hash3Lock();
            //_dataContainer = new DataContainer_HashCon();

            _httpHandler = new HttpHandler();
            //_httpHandler = new TestHttpHandler();//模拟数据

            _dataContainer.AddListUrl(startUrl);
        }

        public void SetHttpHandler(IHttpHandler httpHandler)
        {
            _httpHandler = httpHandler;
        }
        public void SetListPageHandler(IListPageHandler listPageHandler)
        {
            _listPageHandler = listPageHandler;
        }
        public void SetDetailPageHandler(IDetailPageHandler detailPageHandler)
        {
            _detailPageHandler = detailPageHandler;
        }

        public bool Start()
        {
            //初始默认处理
            if (_listPageHandler == null)
            {
                _listPageHandler = new ListPageHandler(_config, _dataContainer, _httpHandler, _crawlerLog);
            }
            if (_detailPageHandler == null)
            {
                _detailPageHandler = new DetailPageHandler(_config, _dataContainer, _httpHandler, _crawlerLog);
            }
            _crawlerLog.Info("初始化成功");

            isRun = true;


            _crawlerLog.Info($"开始服务（线程:{_config.TaskThreadNum}）");

            //处理列表任务
            StartListTaskService();
            //处理明细任务
            StartDetailTaskService();

            return true;
        }

        private void StartListTaskService()
        {
            TaskFactory taskFactory = new TaskFactory();
            for (int i = 0; i < _config.TaskThreadNum; i++)
            {
                taskFactory.StartNew((obj) =>
                {
                    int index = (int)obj;
                    _crawlerLog.Info($"运行处理线程【{index}】");

                    while (true)
                    {
                        //取一个列表url，标记读取
                        string url = _dataContainer.GetOneTask();
                        if (string.IsNullOrEmpty(url))
                        {
                            _crawlerLog.Info($"【线程{index}】无列表页任务");
                            Thread.Sleep(1000);
                            continue;
                        }

                        var task = new TaskContext
                        {
                            Url = url,
                            ThreadIndex = index
                        };
                        _listPageHandler.HandleTask(task);

                        Thread.Sleep(1);
                    }
                }, i);
            }
        }
        private void StartDetailTaskService()
        {
            TaskFactory taskDetailFactory = new TaskFactory();
            for (int i = 0; i < _config.DetailTaskThreadNum; i++)
            {
                taskDetailFactory.StartNew((obj) =>
                {
                    int index = (int)obj;
                    _crawlerLog.Info($"运行明细处理线程【{index}】");

                    while (true)
                    {
                        //取一个列表url，标记读取
                        string url = _dataContainer.GetOneDetailTask();
                        if (string.IsNullOrEmpty(url))
                        {
                            _crawlerLog.Info($"【明细线程{index}】无明细页任务");
                            Thread.Sleep(1000);
                            continue;
                        }

                        //处理明细页
                        TaskContext detailTask = new TaskContext
                        {
                            Url = url,
                            ThreadIndex = index
                        };
                        _detailPageHandler.HandleTask(detailTask);

                        Thread.Sleep(1);
                    }
                }, i);
            }
        }

        public void Pause()
        {
            isRun = false;
        }

        public void Stop()
        {
            isRun = false;
        }

    }
}
